/*
    完成一些琐碎功能的代码
    *简单日志 (后期换成自己实现的日志系统)
    *JSON序列化与反序列化
*/
#pragma once
#include <cstdio>
#include <ctime>
#include <jsoncpp/json/json.h>
#include <memory>
#include <iostream>
#include <sstream>
#include <random>
#include <iomanip>
#include <atomic>

namespace BRpc
{
#define DLEVEL 0
#define ILEVEL 1
#define ELEVEL 2
#define default_level ILEVEL
// 宏定义日志输出
#define LOG(level, format, ...)                                  \
    {                                                            \
        if (level >= default_level)                              \
        {                                                        \
            time_t t = time(NULL);                               \
            struct tm *lt = localtime(&t);                       \
            char time_msg[32] = {0};                             \
            strftime(time_msg, 31, "%m-%d %T", lt);              \
            printf("[%s]"                                        \
                   "[%s:%d]" format "\n",                        \
                   time_msg, __FILE__, __LINE__, ##__VA_ARGS__); \
        }                                                        \
    }

#define DLOG(format, ...) LOG(DLEVEL, format, ##__VA_ARGS__);
#define ILOG(format, ...) LOG(ILEVEL, format, ##__VA_ARGS__);
#define ELOG(format, ...) LOG(ELEVEL, format, ##__VA_ARGS__);
    // Json工具类
    class JsonUtil
    {
    public:
        static bool serialize(const Json::Value &val, std::string &body)
        {
            std::stringstream ss;
            Json::StreamWriterBuilder swb;
            std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
            int ret = sw->write(val, &ss);
            if (ret != 0)
            {
                ELOG("serialize failed");
                return false;
            }
            body = ss.str();
            return true;
        }
        static bool unserialize(const std::string &val, Json::Value &body)
        {
            Json::CharReaderBuilder jcb;
            std::unique_ptr<Json::CharReader> cr(jcb.newCharReader());
            Json::String error;
            bool ret = cr->parse(val.c_str(), val.c_str() + val.size(), &body, &error);
            if (!ret)
            {
                ELOG("unserialize failed:%s", error.c_str());
                return false;
            }
            return true;
        }
    };
//生成随机ID的类
    class UUID
    {
    public:
        static std::string uuid()
        {
            std::stringstream ss;
            // 构建一个随机数种子
            std::random_device rd;
            // 创建一个以随机数种子作为种子的对象
            std::mt19937 gen(rd());
            // 限定随机数范围的对象
            std::uniform_int_distribution<int> dis(0, 255);
            for (int i = 0; i < 8; i++)
            {
                if (i == 4 || i == 6)
                    ss << '-';
                ss << std::setw(2) << std::setfill('0') << std::hex << dis(gen);
            }
            // 定义一个八字节序号,逐字节组成16进制数字字符的字符串
            static std::atomic<size_t> seq(1);
            size_t cur = seq.fetch_add(1);
            for (int i = 7; i >= 0; i--)
            {
                if (i == 5)
                    ss << "-";
                ss << std::setw(2) << std::setfill('0') << std::hex << ((cur >> (i * 8)) & 0xFF);
            }
            return ss.str();
        }
    };
}